<template>
    <div class="flex-col h-full">
        <div class="h-8 flex justify-between items-center  mb-1.5 pb-1.5 border-b border-gray-100">
            <div class="flex">
                <span>
                    <jb-icon :local="true" icon="ri:briefcase-4-fill" height="25" color="#000000a3"></jb-icon>
                </span>&nbsp;&nbsp;
                <span class="text-lg">JBoltAI Development Kit</span>
            </div>
            <div class="flex cursor-pointer">
                <span class="icon-box " :class="isPhone?'active':''" @click="isPhone=true">
                    <jb-icon :local="true" icon="ri:device-line" height="20" color="#000000a3"></jb-icon>
                </span>
                <span class="icon-box" :class="!isPhone?'active':''" @click="showPC()">
                    <jb-icon :local="true" icon="ri:computer-line" height="20" color="#000000a3"></jb-icon>
                </span>
                <span class="icon-box" @click="close()">
                    <jb-icon :local="true" icon="ri:close-fill" height="20" color="#000000a3"></jb-icon>
                </span>
            </div>
        </div>
        <n-layout has-sider class="flex-1 shrink-0 box">
            <n-layout class="content" style="display: flex;flex-direction: column" v-show="isPhone">

                <n-tabs class="tabs" type="line" animated @beforeLeave="changeTabs">
                    <n-tab-pane name="basic" tab="基础">
                        <template #tab>
                            <jb-icon :local="true" icon="ri:settings-5-fill"></jb-icon> &nbsp;
                            基础
                        </template>
                        <Basic style="height: 100%;" :appId="props.appId" @unSaveData="unSaveData" @saveData="saveData"></Basic>
                    </n-tab-pane>
                    <n-tab-pane name="ui" tab="UI布局">
                        <template #tab>
                            <jb-icon :local="true" icon="ri:box-3-fill"></jb-icon> &nbsp;
                            UI布局
                        </template>
                        <ui style="height: 100%" :appId="props.appId" @unSaveData="unSaveData" @saveData="saveData"
                            @update-success="handleUpdateSuccess"
                        ></ui>
                    </n-tab-pane>
                    <n-tab-pane name="function" tab="Function">
                        <template #tab>
                            <jb-icon :local="true" icon="ri:formula"></jb-icon> &nbsp;
                            Function
                        </template>
                        <function style="height: 100%" :appId="props.appId"></function>

                    </n-tab-pane>
                    <n-tab-pane name="knowledge" tab="知识库">
                        <template #tab>
                            <jb-icon :local="true" icon="ix:database-filled"></jb-icon> &nbsp;
                            知识库
                        </template>
                        <Knowledge style="height: 100%" :appId="props.appId"></Knowledge>
                    </n-tab-pane>
                    <n-tab-pane name="llm" tab="LLM参数">
                        <template #tab>
                            <jb-icon :local="true" icon="ri:robot-2-fill"></jb-icon> &nbsp;
                            LLM参数
                        </template>
                        <llm style="height: 100%" :appId="props.appId" @unSaveData="unSaveData" @saveData="saveData"></llm>
                    </n-tab-pane>
                    <n-tab-pane name="public" tab="发布">
                        <template #tab>
                            <jb-icon :local="true" icon="bxs:paper-plane"></jb-icon> &nbsp;
                            发布
                        </template>
                        <Publish style="height: 100%" :appId="props.appId" theme="large"></Publish>
                    </n-tab-pane>
                </n-tabs>


            </n-layout>
            &nbsp; &nbsp; &nbsp; &nbsp;
            <n-layout-sider collapse-mode="width" :collapsed-width="0" :width="isPhone?550:1300"
                            content-style="border:1px solid #e0e0e6;border-radius:10px;">
                <div style="height: 100%" class="chat_panel" ref="chatContainer">

                </div>
            </n-layout-sider>
        </n-layout>
    </div>
</template>

<script setup>
import {
    onMounted,
    onBeforeUnmount,
    ref,
    watch, inject, h
} from "vue";
import Basic from "./cpns/basic/index.vue"
import Ui from "./cpns/ui/index.vue"
import Function from "./cpns/function/index.vue"
import Knowledge from "./cpns/knowledge/index.vue"
import Llm from "./cpns/llm/index.vue"
import Publish from "./cpns/publish/index.vue"
import {
    storeToRefs
} from "pinia";
import {
    useWebSocketStore
} from "@/stores/websocket.js";
import markdownit from "markdown-it";
import {
    JBoltApi
} from "@/service/request/index.js";
import AiChat from "@/components/_builtin/jb-ai-chat/index.js";
import {useDialog, useMessage} from 'naive-ui'
import JbIcon from '@/components/_builtin/jb-icon/index.vue'
import linkAttributes from "markdown-it-link-attributes"
import texmath from "markdown-it-texmath";
import katex from "katex";

function renderIcon(icon) {
    return () => h(JbIcon, {icon, local: true});
}

const message = useMessage()
const dialog = useDialog()

const props = defineProps({
    appId: String,
    klbId: String,
    sessionId: String
})
const isPhone = ref(true);

const pageRef = ref(null)

const webSocketStore = storeToRefs(useWebSocketStore())
const md = markdownit({
    html: true,
    breaks: true,
    linkify: true,
    typographer: true
});
// 使用 texmath 插件，并配置引擎和分隔符
md.use(texmath, {
    engine: katex,
    delimiters: [
        "dollars", "brackets" // 支持美元符号和方括号作为分隔符
    ]

})
// 使用 linkAttributes 插件，并配置目标属性和 rel 属性
md.use(linkAttributes, {
    pattern: /https?:\/\/(www\.)?/i, // 匹配所有 HTTP/HTTPS 链接
    attrs: {
        target: '_blank', // 设置所有链接在新标签页打开
        rel: 'noopener' // 增加这个属性可以提高安全性
    }
})


const chatContainer = ref(null)
const chatInstance = ref(null)
//默认当前的session对象
const currentSession = ref({})
//默认当前的app对象
const appInfo = ref({
    name: '',
    userAvatar: '',
    showAvatar: false,
    assistantAvatar: '',
})

watch(() => useWebSocketStore().ws.value, (newV) => {

    if (chatContainer.value && newV) {
        chatInstance.value.updateWebSocket(useWebSocketStore().ws.value)
    }
})

watch(() => webSocketStore.ws.value, () => {
    console.debug("websock重连")
    if (chatInstance.value) {
        chatInstance.value.updateWebSocket(webSocketStore.ws.value)
    }
})

watch(() => chatContainer.value, (newV) => {
    // console.log(newV);
    if (newV && !chatInstance.value) {
        loadChatInstance()
    }
})
//监听当前的session对象
watch(() => currentSession.value, (newV) => {
    if (newV) {
        if (chatInstance.value) {
            chatInstance.value.destroy();
        }
        if (chatContainer.value) {
            chatState.value = {
                pageSize: 20,
                hasMore: true
            }
            loadChatInstance()
        }
    }

})
watch(() => appInfo.value, () => {
    console.log("监听appInfo")
    if (chatInstance.value) {
        chatInstance.value.destroy();
    }
    if (chatContainer.value) {
        chatState.value = {
            pager: {
                page: 1,
                pageSize: 20,
            },
            hasMore: true,
        }
        loadChatInstance()
    }
})


const chatState = ref({
    pager: {
        page: 1,
        pageSize: 20,
    },
    hasMore: true,
})


watch(() => props.appId, () => {
    if (chatInstance.value) {
        chatInstance.value.destroy();
    }
    if (chatContainer.value) {
        chatState.value = {
            pager: {
                page: 1,
                pageSize: 20,
            },
            hasMore: true,
        }
        loadChatInstance()
    }
})

function showPC() {
    isPhone.value = false
}

function loadChatInstance() {
    //初始化aichat
    chatInstance.value = new AiChat(chatContainer.value, {
        // websocketUrl: 'ws://192.168.31.118:8013/ws',
        websocketInstance: webSocketStore.ws.value,
        app: props.appId,
        sessionId: currentSession.value.id,
        global: null,
        showAvatar: appInfo.value.showAvatar ?? true,
        userAvatar: appInfo.value.userAvatar ?? "",
        assistantAvatar: appInfo.value.assistantAvatar ?? "",
        onClearMsg: async (sessionId) => {
            let res = await JBoltApi.tryGet(`/aiAppMessage/deleteBySessionId/${sessionId}`);
            return true;
        },
        onMsgToDelete: async (id) => {
            console.debug("删除消息", id)
            let {
                result, error
            } = await JBoltApi.get(`/aiAppMessage/delMsgById/${id}`)
            if (result.code == 0) {
                // console.log("成功")
                message.success("删除成功");
                return true;
            }
            if (error) {
                // console.log("失败")
                return false;
            }
        },

        onMarkdownRender: (markdown) => {
            return md.render(markdown);
        },

    },)
}


function handleUpdateSuccess() {
    // 在这里更新父组件的状态，比如改变某个变量的值等
    console.log('收到子组件通知，已更新状态');
    getApp();
}

function addSession() {
    JBoltApi.tryPost('/aiAppSession/add', {
        name: '新的App会话',
        appId: props.appId,
        isDebug: true,
        config: {}
    }).then((res) => {
        currentSession.value = res.data;
    }).catch((error) => {
        console.error(error);
    });
}


function getApp() {
    JBoltApi.tryGet(`/aiApp/getById/${props.appId}`).then((res) => {
        appInfo.value = res.data;
        const uiConfig = res.data.config?.uiConfig;
        if (uiConfig) {
            appInfo.value.showAvatar = !!uiConfig.showAvatar;
            console.debug(uiConfig)
            //如果没有传logo,就用默认JBoltAI头像
            if (uiConfig.appLogo != undefined && uiConfig.appLogo != '') {
                appInfo.value.appLogo = uiConfig.appLogo;
            } else {
                appInfo.value.appLogo = 'https://static.jbolt.cn/website/jboltai_logo_icon.png';
            }
            appInfo.value.assistantAvatar = uiConfig.assistantAvatar;
            appInfo.value.userAvatar = uiConfig.userAvatar;
        } else {
            appInfo.value.appLogo = 'https://static.jbolt.cn/website/jboltai_logo_icon.png';
        }
        // 添加会话
    }).catch((error) => {
        console.error(error);
    });
}

//-------监听用户当前是否有更改的数据
const closeDrawer = inject('closeDrawer');
const updateState = ref(false);

//监听关闭按钮
function close() {
    console.debug("检测到用户要关闭弹窗")
    //判断用户当前数据是否有更改,如果有更改的话,弹窗询问用户,是否要保存
    if (updateState.value == false) {
        console.debug("检测到用户切换标签,没有修改")
        closeDrawer();
    } else {
        console.debug("检测到用户切换标签,有修改");
        // 使用 dialog 创建对话框
        return new Promise((resolve) => {
            dialog.success({
                title: '提示',
                icon: renderIcon("ant-design:exclamation-circle-filled"),
                content: '当前页面有未保存的数据,是否确认离开?',
                positiveText: '仍要离开',
                negativeText: '去保存',
                draggable: true,
                onPositiveClick: () => {
                    // saveData();
                    closeDrawer();
                    // resolve(true); // 允许切换
                },
                onNegativeClick: () => {
                    resolve(false); // 阻止切换
                }
            });
        });

    }

}

//切换标签前前监听
const changeTabs = (newTab, oldTab) => {

    if (updateState.value == false) {
        console.debug("检测到用户切换标签,没有修改")
        return true;
    } else {
        console.debug("检测到用户切换标签,有修改");
        // 使用 dialog 创建对话框
        return new Promise((resolve) => {
            dialog.success({
                icon: renderIcon("ant-design:exclamation-circle-filled"),
                title: '提示',
                content: '当前页面有未保存的数据,是否确认离开?',
                positiveText: '仍要离开',
                negativeText: '去保存',
                draggable: true,
                onPositiveClick: () => {
                    saveData();
                    resolve(true); // 允许切换
                },
                onNegativeClick: () => {
                    resolve(false); // 阻止切换
                }
            });
        });

    }
}
//未保存
const unSaveData = () => {
    updateState.value = true;
    console.debug("未保存")
}
//已保存
const saveData = () => {
    updateState.value = false;
    console.debug("已保存")
}

//-------监听用户当前是否有更改的数据
onMounted(() => {
    getApp();
    addSession();

})
onBeforeUnmount(() => {
    if (chatInstance.value) {
        chatInstance.value.destroy()
    }
})
</script>


<style scoped lang="scss">
.tabs {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: 100%;

    :deep(.n-tabs-nav) {
        flex-shrink: 0;
    }

    :deep(.n-tabs-pane-wrapper) {
        flex: 1;
        height: 100%;
    }

    :deep(.n-tab-pane) {
        height: 100%;
        overflow-y: auto;
    }
}

//.content:deep(.n-layout-scroll-container) {
//  display: flex;
//  flex-direction: column;
//  //height: 100%;
//
//}

.chat_panel {
    background: linear-gradient(135deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
    border-radius: 8px;
}

.icon-box {
    border: 1px solid rgba(121, 121, 121, 0.27);
    display: inline;
    padding: 5px;
}

.icon-box:hover {
    background-color: rgba(121, 121, 121, 0.09);

}

.icon-box:active {
    background-color: rgba(121, 121, 121, 0.09);
}

.active {
    background-color: rgba(121, 121, 121, 0.09);
}

.box :deep(.n-layout-scroll-container) {
    justify-content: center;
}
</style>